from django.http import HttpResponse
from django.core.cache import cache
from django.core.files.storage import FileSystemStorage

from asgiref.sync import async_to_sync
from channels.layers import get_channel_layer
from channels.generic.websocket import AsyncWebsocketConsumer
from channels.generic.websocket import WebsocketConsumer

from ...models.users import Users
from ...models.dall_jobs import DallJob

from ...utils.users import get_login_user_id
from ...utils.data_handle import users_data_paging
from .utils import get_dalljob_handler

from .tasks import dalltasks, testtest

import json


def dall_image(request):
    '''
    创建绘画
    POST
    re = {
        "quality": "standard",
        "size": "1024x1024",
        "style": "vivid",
        "prompt": "maomi",
        "dallpower": 15,
    }
    '''
    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        if json_obj['prompt'] is None or not json_obj['prompt']:
            res_mes = {
                "code": 1,
                "message": "非法参数或参数解析失败"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)

        # 先查询 user_id
        userid = get_login_user_id(request, isadmin=False)
        # print(userid, "会话检测")
        if not userid:
            res_mes = {
                "code": 400,
                "message": "用户没有缓存!"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)

        # 先从redis缓存中获取用户信息
        ## 暂时关闭
        user_cache_mes = cache.get(f'user_info_{userid}')
        if not user_cache_mes:
            # 获取用户信息
            re_user_obj = Users.objects.filter(id=userid).order_by('id')

            # 设置用户信息缓存到redis
            chatusers_tree_json = users_data_paging(re_user_obj, 1, 10)
            cache.set(f'user_info_{userid}', chatusers_tree_json["items"][0], timeout=3600)  # 设置缓存超时时间为3600秒

            user_cache_mes = chatusers_tree_json['items'][0]

        # 查看用户算力是否足够绘画
        if user_cache_mes['power'] < json_obj['dallpower']:
            res_mes = {
                "code": 1,
                "message": "当前用户剩余算力不足以完成本次绘画！"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 创建任务数据到数据库 留存信息
        instance = DallJob(
            user_id = userid,
            prompt = json_obj['prompt'],
            power = json_obj['dallpower'],
        )

        try:
            instance.save()
        except:
            res_mes = {
                "code": 1,
                "message": "保存绘画任务失败！"
            }
            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # # 在视图中触发异步任务

        # res = testtest.delay(2, 4)
        # print(type(res))


        # res_mes = {
        #     "code": 0
        # }
        # res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        # return HttpResponse(res_mes_json)


        result = dalltasks.delay(
                    instance.id,
                    userid,
                    json_obj['prompt'],
                    json_obj['quality'],
                    json_obj['size'],
                    json_obj['style'],
                    json_obj['dallpower']
                )
        from .tasks import some_view

        res = {
            "code": 0,
            "mes": "Task Updated"
        }
        some_view(instance.id, userid, res)

        res_mes = {
            "code": 0
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


def dall_getjobs(request):
    '''
    获取任务列表
    GET
    status: 0是正在进行的任务, 1是完成的
    参数：
    status: 1
    page: 1
    page_size: 15
    '''

    # 先查询 user_id
    userid = get_login_user_id(request, isadmin=False)


    # 获取所有的参数
    get_params = request.GET.dict()
    if "page" not in get_params:
        # 这是查询正在进行中的任务，但是没有传入分页参数
        get_params["page"] = 1
        get_params["page_size"] = 10


    if int(get_params['status']):
        # 1 完成的 进度值应该是等于100
        all_user_dalljob = DallJob.objects.filter(user_id=userid, progress=100).order_by('-created_at')
    else:
        # 0 是进行中的
        all_user_dalljob = DallJob.objects.filter(user_id=userid, progress__gte=0, progress__lt=100).order_by('-created_at')

    all_dalljob = get_dalljob_handler(all_user_dalljob, get_params["page"], get_params["page_size"])


    res_mes = {
        "code": 0,
        "data": all_dalljob
    }
    res_mes_json = json.dumps(res_mes, ensure_ascii=False)
    return HttpResponse(res_mes_json)


def dall_imgwall(request):
    '''
    获取所有公开的照片
    GET

    参数：
    page: 1
    page_size: 15
    '''

    # 获取所有的参数
    get_params = request.GET.dict()

    # 获取数据
    all_user_dalljob = DallJob.objects.filter(progress=100, publish=False).order_by('-created_at')
    all_dalljob = get_dalljob_handler(all_user_dalljob, get_params["page"], get_params["page_size"])

    res_mes = {
        "code": 0,
        "data": all_dalljob
    }
    res_mes_json = json.dumps(res_mes, ensure_ascii=False)
    return HttpResponse(res_mes_json)


def dall_publish(request):
    '''
    POST
    发布作品到作品墙
    body = {
        "id": 8,
        "action": false
    }
    '''
    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        # 更新状态
        try:
            DallJob.objects.filter(id=json_obj['id']).update(publish=json_obj['action'])
        except:
            res_mes = {
                "code": 1,
                "message": "更新数据库失败!"
            }

        res_mes = {
            "code": 0
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


def dall_remove(request):
    '''
    删除图片任务
    POST
    body = {
        "id": 7,
        "img_url": "/media/dallimages/2024/09/03/9485422262762168.png",
        "user_id": 3
    }
    '''
    if request.method == 'POST':
        json_b = request.body
        json_str = json_b.decode('utf-8')
        json_obj = json.loads(json_str)

        # 删除数据库任务记录
        try:
            DallJob.objects.filter(id=json_obj['id'], user_id=json_obj['user_id']).delete()
        except:
            res_mes = {
                "code": 1,
                "message": "删除任务失败！"
            }

            res_mes_json = json.dumps(res_mes, ensure_ascii=False)
            return HttpResponse(res_mes_json)
        
        # 删除保存的图片
        try:
            del_img_url = json_obj['img_url'].replace("/media/", "")
            del_thumb_url = json_obj['thumb_url'].replace("/media/", "")
            fs = FileSystemStorage()

            fs.delete(del_img_url)
            fs.delete(del_thumb_url)
        except:
            pass

        res_mes = {
            "code": 0
        }
        res_mes_json = json.dumps(res_mes, ensure_ascii=False)
        return HttpResponse(res_mes_json)


# dall websock 用于通知任务状态
class DallClient(WebsocketConsumer):
    def connect(self):
        '''
        参数：
        user_id: 3
        '''
        # 先接受链接

        query_string = self.scope['query_string'].decode('utf-8')
        user_id = int(query_string.split("=")[1])


        async_to_sync(self.channel_layer.group_add)(f'user_{user_id}', self.channel_name)
        self.accept()


    ################################################################
    # 当收到客户端发送过来的消息 处理阶段
    def receive(self, text_data):
        '''
        心跳：{'type': 'heartbeat', 'content': 'ping'}
        对话：{"type":"chat","content":"你好"}
        '''
        pass

    ################################################################
    # 断开链接
    def disconnect(self, close_code):
        print("用户断开了链接！")
        # await self.close()
 

    # ################################################################
    def my_event(self, event):
        # 处理消息
        message = event['message']
        # 然后你可以通过self.send来向WebSocket客户端发送消息
        a = message.encode('utf-8')
        self.send(bytes_data=a)
